﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Widgetsphere.Core
{
	public class Extensions
	{
		/// <summary>
		/// This extension allows you to define a non-nullable reference type.
		/// </summary>
		/// <typeparam name="T"></typeparam>
		public struct NotNull<T> where T : class
		{
			public readonly T value;

			public NotNull(T arg)
			{
				if (arg == null)
					throw new ArgumentNullException("arg");

				value = arg;
			}

			// convert non-nullable to regular  
			public static implicit operator T(NotNull<T> arg)
			{
				return arg.value;
			}

			// convert regular to non-nullable  
			public static implicit operator NotNull<T>(T arg)
			{
				return new NotNull<T>(arg);
			}

			// explicit cast to non-nullable -- needed when T == object  
			public static NotNull<object> Cast(object arg)
			{
				return new NotNull<object>(arg);
			}

			public override string ToString()
			{
				return value.ToString();
			}

			public override bool Equals(object obj)
			{
				return value.Equals(obj);
			}

			public override int GetHashCode()
			{
				return value.GetHashCode();
			}

			public static bool operator ==(NotNull<T> left, NotNull<T> right)
			{
				return Equals(left, right);
			}

			public static bool operator !=(NotNull<T> left, NotNull<T> right)
			{
				return !Equals(left, right);
			}
		}
	}
}
